import os
from sc_engine.apps import messages as msgs

from sc_engine.repositories import Repository, use
from sc_engine.repositories.participant import ParticipantRepository
from sc_engine.repositories.waiting import WaitingDataRepository
from sc_engine.repositories.stores import PickleFileStore

def make_app(app_name, root_config, config):
    data_directory = root_config['data_directory']

    store_filename = os.path.join(data_directory, app_name)
    store = PickleFileStore(store_filename)
    repo = Repository(store)

    app = ProleagueScheduleParseApp(repo)

    return {
        msgs.TeamDataAnnouncement: app.team_data_announcement,
        msgs.LeagueDataAnnouncement: app.league_data_announcement,
        msgs.LeagueStagePathDateAnnouncement: app.league_stage_path_date_announcement,
        msgs.ProleagueMatchFetchAnnouncement: app.proleague_match_fetch_announcement,
        msgs.ProleagueGameFetchAnnouncement: app.proleague_game_fetch_announcement,
    }

class ProleagueScheduleParseApp(object):
    """Parse a proleague schedule.

    Retrieves the fetched data from a proleague schedule, and will try to parse
    it into data understandable by the rest of the engine. This may mean
    converting into a league, stage_path, and match_id before even touching
    stuff such as players or maps. May need to wait for match_ids to be
    generated.
    """
    WIN_BY_FORFEIT_MAP = 1003

    def __init__(self, repo):
        self.repo = repo
        repo.add_repository('teams', ParticipantRepository)
        repo.add_repository('waiting', WaitingDataRepository)

    @use('repo', 'teams')
    def team_data_announcement(self, msg, teams):
        teams.update(msg.team_id, msg.name, msg.aliases)

    @use('repo', 'leagues', 'league_stages')
    def league_data_announcement(self, msg, leagues, league_stages):
        leagues[msg.alias] = msg.name_key
        league_stages[msg.name_key] = {}

    @use('repo', 'league_stages', 'waiting')
    def league_stage_path_date_announcement(self, msg, league_stages, waiting):
        league = league_stages[msg.league]
        league[msg.date] = msg.stage_path

        results = waiting.run(msg)
        return results

    @use('repo', 'leagues', 'league_stages', 'teams')
    def _get_info(self, msg, leagues, league_stages, teams):
        league = leagues[msg.league]
        stage_path = league_stages[league].get(msg.date_played, None)
        team_one = teams.find_participant(msg.team_one)
        team_two = teams.find_participant(msg.team_two)

        return league, stage_path, team_one, team_two

    @use('repo', 'teams', 'waiting')
    def proleague_match_fetch_announcement(self, msg, teams, waiting):
        league, stage_path, team_one, team_two = self._get_info(msg)

        if stage_path == None:
            filter_dict = {'date' : msg.date_played} 
            waiting.add(msg,msgs.LeagueStagePathDateAnnouncement, filter_dict)

            return msgs.LeagueStagePathDateRequested(league, msg.stage, msg.date_played)

        if msg.winner is not None:
            winner = teams.find_participant(msg.winner)
        else:
            winner = None

        return msgs.ProleagueMatchParseAnnouncement(
            league,
            stage_path,
            team_one,
            team_two,
            winner, msg.winner_score, msg.loser_score)

    @use('repo', 'waiting')
    def proleague_game_fetch_announcement(self, msg, waiting):
        league, stage_path, team_one, team_two = self._get_info(msg)

        if stage_path == None:
            filter_dict = {'date' : msg.date_played}
            waiting.add(msg,msgs.LeagueStagePathDateAnnouncement, filter_dict)
            return

        game_map = None if msg.game_map == self.WIN_BY_FORFEIT_MAP else msg.game_map

        return msgs.ProleagueGameParseAnnouncement(
            league, stage_path, team_one, team_two,
            msg.date_played, msg.game_number, game_map,
            msg.player_one, msg.player_one_start_location,
            msg.player_two, msg.player_two_start_location,
            msg.winner, msg.playtime)

